---
title: template.{pkl,yml}
toc_max_heading_level: 6
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import HeadingApiLink from '@site/src/components/Docs/HeadingApiLink';
import RequiredLabel from '@site/src/components/Docs/RequiredLabel';
import VersionLabel from '@site/src/components/Docs/VersionLabel';

The `template.yml` file configures metadata and variables for a template,
[used by the generator](../guides/codegen), and must exist at the root of a named template folder.

```yaml title="template.yml"
$schema: 'https://moonrepo.dev/schemas/template.json'
```

:::info

Template configuration can also be written in [Pkl](../guides/pkl-config) instead of YAML.

:::

## `id`<VersionLabel version="1.23.0" />

<HeadingApiLink to="/api/types/interface/TemplateConfig#id" />

Overrides the name (identifier) of the template, instead of inferring the name from the template
folder. Be aware that template names must be unique across the workspace, and across all template
locations that have been configured in [`generator.templates`](./workspace#templates).

```yaml title="template.yml"
id: 'npm-package'
```

## `title`<RequiredLabel />

<HeadingApiLink to="/api/types/interface/TemplateConfig#title" />

A human readable title that will be displayed during the [`moon generate`](../commands/generate)
process.

```yaml title="template.yml"
title: 'npm package'
```

## `description`<RequiredLabel />

<HeadingApiLink to="/api/types/interface/TemplateConfig#description" />

A description of why the template exists, what its purpose is, and any other relevant information.

```yaml title="template.yml"
description: |
  Scaffolds the initial structure for an npm package,
  including source and test folders, a package.json, and more.
```

## `destination`<VersionLabel version="1.19.0" />

<HeadingApiLink to="/api/types/interface/TemplateConfig#destination" />

An optional file path in which this template should be generated into. This provides a mechanism for
standardizing a destination location, and avoids having to manually pass a destination to
[`moon generate`](../commands/generate).

If the destination is prefixed with `/`, it will be relative from the workspace root, otherwise it
is relative from the current working directory.

```yaml title="template.yml"
destination: 'packages/[name]'
```

> This setting supports [template variables](#variables) through `[varName]` syntax. Learn more in
> the [code generation documentation](../guides/codegen#interpolation).

## `extends`<VersionLabel version="1.19.0" />

<HeadingApiLink to="/api/types/interface/TemplateConfig#extends" />

One or many other templates that this template should extend. Will deeply inherit all template files
and variables.

```yaml title="template.yml"
extends: ['base', 'configs']
```

## `variables`

<HeadingApiLink to="/api/types/interface/TemplateConfig#variables" />

A mapping of variables that will be interpolated into all template files and file system paths when
[rendering with Tera](https://tera.netlify.app/docs/#variables). The map key is the variable name
(in camelCase or snake_case), while the value is a configuration object, as described with the
settings below.

```yaml title="template.yml"
variables:
  name:
    type: 'string'
    default: ''
    required: true
    prompt: 'Package name?'
```

### `type`<RequiredLabel />

The type of value for the variable. Accepts `array`, `boolean`, `string`, `object`, `number`, or
`enum`. Floats _are not supported_, use strings instead.

For arrays and objects, the value of each member must be a JSON compatible type.

### `internal`<VersionLabel version="1.23.0" />

<HeadingApiLink to="/api/types/interface/TemplateVariableStringSetting#internal" />

Marks a variable as internal only, which avoids the variable value being overwritten by command line
arguments.

### `order`<VersionLabel version="1.23.0" />

<HeadingApiLink to="/api/types/interface/TemplateVariableStringSetting#order" />

The order in which the variable will be prompted to the user. By default, variables are prompted in
the order they are defined in the `template.yml` file.

### Primitives & collections

Your basic primitives: boolean, numbers, strings, and collections: arrays, objects.

<Tabs
  groupId="types"
  defaultValue="array"
  values={[{ value: 'array' }, { value: 'boolean' }, { value: 'number' }, { value: 'object' }, { value: 'string' }]}
>
<TabItem value="array">

```yaml title="template.yml"
variables:
  type:
    type: 'array'
    prompt: 'Type?'
    default: ['app', 'lib']
```

</TabItem>
<TabItem value="boolean">

```yaml title="template.yml"
variables:
  private:
    type: 'boolean'
    prompt: 'Private?'
    default: false
```

</TabItem>
<TabItem value="number">

```yaml title="template.yml"
variables:
  age:
    type: 'number'
    prompt: 'Age?'
    default: 0
    required: true
```

</TabItem>
<TabItem value="object">

```yaml title="template.yml"
variables:
  metadata:
    type: 'object'
    prompt: 'Metadata?'
    default:
      type: 'lib'
      dev: true
```

</TabItem>
<TabItem value="string">

```yaml title="template.yml"
variables:
  name:
    type: 'string'
    prompt: 'Name?'
    required: true
```

</TabItem>
</Tabs>

### `default`<RequiredLabel />

<HeadingApiLink to="/api/types/interface/TemplateVariableStringSetting#default" />

The default value of the variable. When `--defaults` is passed to
[`moon generate`](../commands/generate) or [`prompt`](#prompt) is not defined, the default value
will be used, otherwise the user will be prompted to enter a custom value.

### `prompt`

<HeadingApiLink to="/api/types/interface/TemplateVariableStringSetting#prompt" />

When defined, will prompt the user with a message in the terminal to input a custom value, otherwise
[`default`](#default) will be used.

For arrays and objects, a valid JSON string must be provided as the value.

### `required`

<HeadingApiLink to="/api/types/interface/TemplateVariableStringSetting#required" />

Marks the variable as required during _prompting only_. For arrays, strings, and objects, will error
for empty values (`''`). For numbers, will error for zero's (`0`).

### Enums

An enum is an explicit list of string values that a user can choose from.

```yaml title="template.yml"
variables:
  color:
    type: 'enum'
    values: ['red', 'green', 'blue', 'purple']
    default: 'purple'
    prompt: 'Favorite color?'
```

### `default`

<HeadingApiLink to="/api/types/interface/TemplateVariableConfig#default" />

The default value of the variable. When `--defaults` is passed to
[`moon generate`](../commands/generate) or [`prompt`](#prompt) is not defined, the default value
will be used, otherwise the user will be prompted to enter a custom value.

For enums, the default value can be a string when [`multiple`](#multiple) is false, or a string or
an array of strings when `multiple` is true. Furthermore, each default value must exist in the
[`values`](#values) list.

```yaml title="template.yml"
# Single
variables:
  color:
    type: 'enum'
    values: ['red', 'green', 'blue', 'purple']
    default: 'purple'
    prompt: 'Favorite color?'

# Multiple
variables:
  color:
    type: 'enum'
    values: ['red', 'green', 'blue', 'purple']
    default: ['red', 'purple']
    multiple: true
    prompt: 'Favorite color?'
```

### `prompt`

<HeadingApiLink to="/api/types/interface/TemplateVariableConfig#prompt" />

When defined, will prompt the user with a message in the terminal to input a custom value, otherwise
[`default`](#default) will be used.

### `multiple`

<HeadingApiLink to="/api/types/interface/TemplateEnumVariableConfig#multiple" />

Allows multiple values to be chosen during prompting. In the template, an array or strings will be
rendered, otherwise when not-multiple, a single string will be.

### `values`<RequiredLabel />

<HeadingApiLink to="/api/types/interface/TemplateEnumVariableConfig#values" />

List of explicit values to choose from. Can either be defined with a string, which acts as a value
and label, or as an object, which defines an explicit value and label.

```yaml title="template.yml"
variables:
  color:
    type: 'enum'
    values:
      - 'red'
      # OR
      - value: 'red'
        label: 'Red 🔴'
    # ...
```

## Frontmatter

The following settings _are not_ available in `template.yml`, but can be defined as frontmatter at
the top of a template file. View the [code generation guide](../guides/codegen#frontmatter) for more
information.

### `force`

<HeadingApiLink to="/api/types/interface/TemplateFrontmatterConfig#force" />

When enabled, will always overwrite a file of the same name at the destination path, and will bypass
any prompting in the terminal.

```twig
---
force: true
---

Some template content!
```

### `to`

<HeadingApiLink to="/api/types/interface/TemplateFrontmatterConfig#to" />

Defines a custom file path, relative from the destination root, in which to create the file. This
will override the file path within the template folder, and allow for conditional rendering and
engine filters to be used.

```twig
{% set component_name = name | pascal_case %}

---
to: components/{{ component_name }}.tsx
---

export function {{ component_name }}() {
  return <div />;
}
```

### `skip`

<HeadingApiLink to="/api/types/interface/TemplateFrontmatterConfig#skip" />

When enabled, the template file will be skipped while writing to the destination path. This setting
can be used to conditionally render a file.

```twig
---
skip: {{ name == "someCondition" }}
---

Some template content!
```
